package com.eastfair.home.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
//import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.eastfair.annotation.annotation.cache.Cache;
import com.eastfair.annotation.annotation.cache.Magic;
import com.eastfair.boot.request.PageParams;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.exception.BizException;
import com.eastfair.home.dao.HomeServiceItemMapper;
import com.eastfair.home.dto.HomeServiceItemDTO;
import com.eastfair.home.entity.HomeServiceItem;
import com.eastfair.home.entity.ReportSpaceAudit;
import com.eastfair.home.exceptioncode.HomeExceptionCode;
import com.eastfair.home.service.HomeServiceItemService;
import com.eastfair.home.service.ReportSpaceAuditService;
import com.eastfair.home.vo.HomeServiceItemVO;
import com.eastfair.projectcore.enumeration.DataIsolationSystemSceneEnum;
import com.eastfair.venuebooking.api.ServiceCategoryFeign;
import com.eastfair.venuebooking.api.ServiceItemFeign;
import com.eastfair.venueservice.dto.ServiceItemDTO;
import com.eastfair.venueservice.dto.ServiceItemQuery;
import com.eastfair.venueservice.vo.ServiceCategoryVO;
import com.eastfair.venueservice.vo.ServiceItemVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 业务实现类
 * 服务项
 * </p>
 *
 * @author linan
 * @date 2022-07-28
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class HomeServiceItemServiceImpl extends SuperServiceImpl<HomeServiceItemMapper, HomeServiceItem> implements HomeServiceItemService {

    @Resource
    private ServiceItemFeign serviceItemFeign;
    @Resource
    private ServiceCategoryFeign serviceCategoryFeign;
    @Resource
    private ReportSpaceAuditService reportSpaceAuditService;


    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<HomeServiceItem> modelList) {
        modelList.stream().forEach(s -> {
            s.setIsDeleted(BusinessConstant.YES);
        });
        // TODO: 2021/10/29 这里需要操作其他业务，如清空角色等
        return R.successDef();
    }

    /**
     * 通用查询
     *
     * @param modelDTO DTO
     * @param ids 主键id集合
     * @return list
     */
    @Override
    public List<HomeServiceItem> list(HomeServiceItemDTO modelDTO, List<Long> ids) {
        return ((HomeServiceItemService) AopContext.currentProxy()).listOfCache(modelDTO, ids);
    }


    /**
     * 缓存查询
     *
     * @param modelDTO DTO
     * @param ids 主键id集合
     * @return list
     */
    @Override
    @Cache(key = "",
            magic = @Magic(
                    key = "{"+
                            "{'sourceId', #args[0]?.sourceId},"+
                            "{'sourceProvider', #args[0]?.sourceProvider},"+
                            "{'isEnabled', #args[0]?.isEnabled},"+
                            "{'serviceName', #args[0]?.serviceName},"+
                            "{'serviceNo', #args[0]?.serviceNo},"+
                            "{'picUrl', #args[0]?.picUrl},"+
                            "{'serviceCategoryId', #args[0]?.serviceCategoryId},"+
                            "{'calUnit', #args[0]?.calUnit},"+
                            "{'minAllocatedNum', #args[0]?.minAllocatedNum},"+
                            "{'serviceProviderId', #args[0]?.serviceProviderId},"+
                            "{'serviceProviderType', #args[0]?.serviceProviderType},"+
                            "{'serviceState', #args[0]?.serviceState},"+
                            "{'auditState', #args[0]?.auditState},"+
                            "{'exhibitionManageId', #args[0]?.exhibitionManageId},"+
                            "{'id', #args[1]}"+
                            "}"))
    public List<HomeServiceItem> listOfCache(HomeServiceItemDTO modelDTO, List<Long> ids) {
        //查询
        QueryWrapper<HomeServiceItem> queryWrapper = new QueryWrapper<>();
        if (modelDTO != null) {
            queryWrapper.lambda().eq(modelDTO.getSourceId() != null,HomeServiceItem::getSourceId,modelDTO.getSourceId());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getSourceProvider()),HomeServiceItem::getSourceProvider,modelDTO.getSourceProvider());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getServiceName()),HomeServiceItem::getServiceName,modelDTO.getServiceName());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getServiceNo()),HomeServiceItem::getServiceNo,modelDTO.getServiceNo());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getPicUrl()),HomeServiceItem::getPicUrl,modelDTO.getPicUrl());
            queryWrapper.lambda().eq(modelDTO.getServiceCategoryId() != null,HomeServiceItem::getServiceCategoryId,modelDTO.getServiceCategoryId());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getCalUnit()),HomeServiceItem::getCalUnit,modelDTO.getCalUnit());
            queryWrapper.lambda().eq(modelDTO.getMinAllocatedNum() != null,HomeServiceItem::getMinAllocatedNum,modelDTO.getMinAllocatedNum());
            queryWrapper.lambda().eq(modelDTO.getServiceProviderId() != null,HomeServiceItem::getServiceProviderId,modelDTO.getServiceProviderId());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getServiceProviderType()),HomeServiceItem::getServiceProviderType,modelDTO.getServiceProviderType());
            queryWrapper.lambda().eq(Objects.isNull(modelDTO.getServiceState()),HomeServiceItem::getServiceState,modelDTO.getServiceState());
            queryWrapper.lambda().eq(Objects.isNull(modelDTO.getAuditState()),HomeServiceItem::getAuditState,modelDTO.getAuditState());
            queryWrapper.lambda().eq(modelDTO.getExhibitionManageId() != null,HomeServiceItem::getExhibitionManageId,modelDTO.getExhibitionManageId());
        }
        if (ids != null && !ids.isEmpty()) {
            queryWrapper.lambda().in(HomeServiceItem::getId, ids);
        }
        queryWrapper.lambda().eq(HomeServiceItem::getIsDeleted, BusinessConstant.DELETE_NO);
        return list(queryWrapper);
    }

    @Override
    public R<Boolean> addServiceItem(ServiceItemDTO serviceItemDTO) {
        // 校验是否存在非取消的报馆记录
        Long serviceCategoryId = serviceItemDTO.getServiceCategoryId();
        R<List<ServiceCategoryVO>> categoryListByIds = serviceCategoryFeign.getCategoryListByIds(Arrays.asList(serviceCategoryId));
        Integer isManage = 0;
        for (ServiceCategoryVO serviceCategoryVO : categoryListByIds.getData()) {
            if (serviceCategoryVO.getIsManage() == 1) {
                isManage = 1;
            }
        }
        if (isManage == 1) {
            int count = reportSpaceAuditService.count(new QueryWrapper<ReportSpaceAudit>()
                    .lambda().eq(ReportSpaceAudit::getExhibitionId, serviceItemDTO.getExhibitionManageId())
                    .eq(ReportSpaceAudit::getIsDeleted, BusinessConstant.NO)
            );
            if(count>0){
                throw BizException.wrap(HomeExceptionCode.EXIST_REPORT_SPACE_CANT_DEAL_SERVICE_TIME);
            }
        }
        serviceItemDTO.setServiceProviderType(DataIsolationSystemSceneEnum.P_COMPOSITE_COURT.getCode());
        R<Boolean> booleanR = serviceItemFeign.addServiceItem(serviceItemDTO);
        if (!booleanR.getIsSuccess()) {
            throw new BizException(booleanR.getCode(), booleanR.getMsg());
        }
        return booleanR;
    }

    @Override
    public R<Boolean> updateServiceItem(ServiceItemDTO serviceItemDTO) {
        serviceItemDTO.setServiceProviderType(DataIsolationSystemSceneEnum.P_COMPOSITE_COURT.getCode());
        R<Boolean> booleanR = serviceItemFeign.updateServiceItem(serviceItemDTO);
        if (!booleanR.getIsSuccess()) {
            throw new BizException(booleanR.getCode(), booleanR.getMsg());
        }
        return booleanR;
    }

    @Override
    public R<Boolean> shelfService(ServiceItemDTO serviceItemDTO) {
        R<Boolean> booleanR = serviceItemFeign.shelfService(serviceItemDTO);
        if (!booleanR.getIsSuccess()) {
            throw new BizException(booleanR.getCode(), booleanR.getMsg());
        }
        return booleanR;
    }

    @Override
    public R<Boolean> offShelfService(ServiceItemDTO serviceItemDTO) {
        R<Boolean> booleanR = serviceItemFeign.offShelfService(serviceItemDTO);
        if (!booleanR.getIsSuccess()) {
            throw new BizException(booleanR.getCode(), booleanR.getMsg());
        }
        return booleanR;
    }

    @Override
    public R<Boolean> delHomeServiceItemById(ServiceItemDTO serviceItemDTO) {
        R<Boolean> booleanR = serviceItemFeign.delServiceItem(serviceItemDTO);
        if (!booleanR.getIsSuccess()) {
            throw new BizException(booleanR.getCode(), booleanR.getMsg());
        }
        return booleanR;
    }

    @Override
    public IPage<ServiceItemVO> queryServiceItemList(PageParams<ServiceItemQuery> params) {
        params.getModel().setServiceProviderType(DataIsolationSystemSceneEnum.P_COMPOSITE_COURT.getCode());
        IPage<ServiceItemVO> re = params.buildPage();
        R<IPage<ServiceItemVO>> r = (R<IPage<ServiceItemVO>>) serviceItemFeign.queryServiceItem(params);
        if(!r.getIsSuccess()){
            throw BizException.wrap(r.getCode(),r.getMsg());
        }
        BeanUtil.copyProperties(r.getData(), re);
        return re;
    }


    /**
     * do转vo
     * @param model model
     * @return modelVo
     */
    @Override
    public HomeServiceItemVO doToVo(HomeServiceItem model) {
        HomeServiceItemVO modelVo = new HomeServiceItemVO();
        BeanUtils.copyProperties(model, modelVo);
        modelVo.setId(model.getId());
        return modelVo;
    }
    /**
     * do转vo
     * @param modelList modelList
     * @return list
     */
    @Override
    public List<HomeServiceItemVO> doToVos(List<HomeServiceItem> modelList) {
        if (modelList == null || modelList.isEmpty()) {
            return null;
        }
        List<HomeServiceItemVO> result = new ArrayList<>();
        for (HomeServiceItem model : modelList) {
            result.add(doToVo(model));
        }
        return result;
    }
}
